﻿namespace WebMarkupMin.WebForms.MasterPages
{
	using System.IO;
	using System.Text;
	using System.Web;
	using System.Web.UI;

	using Core;
	using Core.Minifiers;
	using Web;

	/// <summary>
	/// Base class of master page with support of markup minification and GZIP/Deflate compression
	/// </summary>
	public abstract class MinifiedAndCompressedMasterPageBase : CompressedMasterPage
	{
		/// <summary>
		/// Flag for whether to enable markup minification
		/// </summary>
		private bool _enableMinification = true;
		private bool _enableMinificationSet;

		/// <summary>
		/// Gets or sets a flag for whether to enable markup minification
		/// </summary>
		public bool EnableMinification
		{
			get
			{
				if (!_enableMinificationSet)
				{
					return WebMarkupMinContext.Current.IsMinificationEnabled();
				}

				return _enableMinification;
			}
			set
			{
				_enableMinification = value;
				_enableMinificationSet = true;
			}
		}


		/// <summary>
		/// Renders a page content with markup minification
		/// </summary>
		/// <typeparam name="T">Type of markup minifier</typeparam>
		/// <param name="writer">HTML text writer that receives the page content</param>
		/// <param name="context">HTTP context</param>
		/// <param name="minifier">Markup minifier</param>
		protected void RenderWithMarkupMinification<T>(HtmlTextWriter writer, HttpContext context,
			T minifier) where T : IMarkupMinifier
		{
			using (var htmlwriter = new HtmlTextWriter(new StringWriter()))
			{
				base.Render(htmlwriter);

				string content = htmlwriter.InnerWriter.ToString();
				bool isMinified = false;

				HttpResponse response = context.Response;
				HttpRequest request = context.Request;
				Encoding encoding = response.ContentEncoding;
				int responseSize = encoding.GetByteCount(content);
				string currentUrl = request.RawUrl;

				if (response.StatusCode == 200 && WebMarkupMinContext.Current.CheckResponseSize(responseSize))
				{
					MarkupMinificationResult minificationResult = minifier.Minify(content,
						currentUrl, encoding, false);
					if (minificationResult.Errors.Count == 0)
					{
						writer.Write(minificationResult.MinifiedContent);
						isMinified = true;
					}
				}

				if (!isMinified)
				{
					writer.Write(content);
				}
			}
		}
	}
}